/*****************************************************************//**
 * \file   StringTool.cpp
 * \brief  StringTool
 *
 * \author Wyatt
 * \date   May 2023
 *********************************************************************/
#include "StringTool.h"
#include <vector>
#include <string>
#include <unordered_map>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>

#include "Define.h"

bool string2Integer(std::string strString, int& nInterger)
{
	int nLength = strString.size();
	int nIndex = 0;
	bool bReachMinus = false;
	nInterger = 0;
	while (nIndex < nLength)
	{
		if (strString[nIndex] == '-')
		{
			bReachMinus = !bReachMinus;
		}
		else if (strString[nIndex] == '+')
		{
			nIndex++;
			continue;
		}
		else
		{
			if (strString[nIndex] < '0' || strString[nIndex]>'9')
				return false;
			nInterger *= 10;
			nInterger += (strString[nIndex] - '0');
		}
		nIndex++;
	}
	if (bReachMinus)
	{
		nInterger = -nInterger;
	}
	return true;
}

bool string2Integer(std::string strString, SKey& nInterger)
{
	int nLength = strString.size();
	int nIndex = 0;
	nInterger = 0;
	while (nIndex < nLength)
	{
		if (strString[nIndex] == '+')
		{
			nIndex++;
			continue;
		}
		else
		{
			if (strString[nIndex] < '0' || strString[nIndex]>'9')
				return false;
			nInterger *= 10;
			nInterger += (strString[nIndex] - '0');
		}
		nIndex++;
	}
	return true;
}

bool string2Float(std::string strString, float& fFloat)
{
	int   nLength = strString.size();
	int   nIndex = 0, nDotPow = 1;
	bool  bCrossDot = false, bReachMinus = false;
	fFloat = (float)0.0;
	while (nIndex < nLength)
	{
		if (strString[nIndex] == '.') bCrossDot = true;
		else if (strString[nIndex] == '-') bReachMinus = !bReachMinus;
		else if (strString[nIndex] == '+')
		{
			continue;
			nIndex++;
		}
		else
		{
			if (bCrossDot == false)
			{
				fFloat *= 10;
				fFloat += (strString[nIndex] - '0');

			}
			else
			{
				fFloat += (float)((strString[nIndex] - '0') * pow(0.1, nDotPow));
				nDotPow++;
			}
		}
		nIndex++;
	}

	if (bReachMinus) fFloat = -fFloat;
	return true;
}

bool string2Float(std::string strString, double& ddouble)
{
	int   nLength = strString.size();
	int   nIndex = 0, nDotPow = 1;
	bool  bCrossDot = false, bReachMinus = false;
	ddouble = (double)0.0;
	while (nIndex < nLength)
	{
		if (strString[nIndex] == '\n' || strString[nIndex] == '\r' || strString[nIndex] == '\t') break;
		if (strString[nIndex] == '.') bCrossDot = true;
		else if (strString[nIndex] == '-') bReachMinus = !bReachMinus;
		else if (strString[nIndex] == '+')
		{
			nIndex++;
			continue;
		}
		else
		{
			if (bCrossDot == false)
			{
				ddouble *= 10;
				ddouble += (strString[nIndex] - '0');
			}
			else
			{
				ddouble += (double)((strString[nIndex] - '0') * pow(0.1, nDotPow));
				nDotPow++;
			}
		}
		nIndex++;
	}

	if (bReachMinus) ddouble = -ddouble;
	return true;
}

bool string2Double(std::string strString, float& fReal)
{
	fReal = FLT_MAX;
	if (strString.empty())
		return true;
	int nStringLength = strString.size();
	float dLeft = 0.0;
	int nPowNum = 0;
	int nSign = -1;

	nSign = stringFirstOf(strString, "eED");
	if (-1 == nSign)
	{
		if (!string2Float(strString.substr(0, nSign), dLeft))
			return false;
		if (!string2Integer(strString.substr(nSign - 1), nPowNum))
			return false;
	}
	else
	{
		if (-1 == nSign)
		{
			if (!string2Float(strString, dLeft))
				return false;
		}
		else if (nSign != 0)
		{
			if (!string2Float(strString.substr(0, nSign), dLeft))
				return false;
			if (!string2Integer(strString.substr(nSign), nPowNum))
				return false;
		}
		else
		{
			int nReverse = stringLastOf(strString, "+-");
			nReverse = strString.size() - 1 - nReverse;
			if (nReverse == nStringLength - 1)
			{
				if (!string2Float(strString, dLeft))
					return false;
			}
			else
			{
				if (!string2Float(strString.substr(0, nStringLength - nReverse - 1), dLeft))
					return false;
				if (!string2Integer(strString.substr(nStringLength - nReverse - 1), nPowNum))
					return false;
			}
		}
	}
	fReal = (dLeft * pow(10.0, nPowNum));
	return true;
}

bool string2Double(std::string strString, double& dReal)
{
	dReal = DEFAUL_DBL;
	if (strString.empty())
		return true;
	int nStringLength = strString.size();
	double dLeft = 0.0;
	int nPowNum = 0;
	int nSign = -1;

	nSign = stringFirstOf(strString, "eED");
	if (-1 == nSign)
	{
		if (!string2Float(strString.substr(0, nSign), dLeft))
			return false;
	}
	else
	{
		if (-1 == nSign)
		{
			if (!string2Float(strString, dLeft))
				return false;
		}
		else if (nSign != 0)
		{
			if (!string2Float(strString.substr(0, nSign), dLeft))
				return false;
			if (!string2Integer(strString.substr(nSign + 1), nPowNum))
				return false;
		}
		else
		{
			int nReverse = stringLastOf(strString, "+-");
			nReverse = strString.size() - 1 - nReverse;
			if (nReverse == nStringLength - 1)
			{
				if (!string2Float(strString, dLeft))
					return false;
			}
			else
			{
				if (!string2Float(strString.substr(0, nStringLength - nReverse - 1), dLeft))
					return false;
				if (!string2Integer(strString.substr(nStringLength - nReverse - 1), nPowNum))
					return false;
			}
		}
	}
	dReal = (dLeft * (double)pow(10.0, nPowNum));
	return true;
}
